﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Net.Http;
using System.Net.Http.Formatting;
using ScrumFactory.Extensions;

namespace ScrumFactory.Services.Clients {

    [Export(typeof(ITasksService))]
    public class TasksServiceClient : ITasksService {

        [Import]
        private IClientHelper ClientHelper { get; set; }

        [Import(typeof(IServerUrl))]
        private IServerUrl serverUrl { get; set; }

        [Import("TasksServiceUrl")]
        private string serviceUrl { get; set; }

        [Import(typeof(IAuthorizationService))]
        private IAuthorizationService authorizator { get; set; }

        private string SafeMemberUId(string memberUId) {
            return memberUId.Replace("#", "@@@").Replace("\\", "@@").Trim();
        }


        private Uri Url(string relative) {
            return new Uri(serviceUrl.Replace("$ScrumFactoryServer$", serverUrl.Url) + relative);
        }

        public ICollection<Task> GetProjectTasks(string projectUId, System.DateTime fromDate, System.DateTime toDate, bool dailyTasksOnly) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("ProjectTasks/" + projectUId + "/?fromDate=" + fromDate.ToString("yyyy-MM-dd") + "&toDate=" + toDate.ToString("yyyy-MM-dd") + "&dailyTasksOnly=" + dailyTasksOnly));
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<ICollection<Task>>();
        }

        public ICollection<Task> GetItemTasks(string backlogitemUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("ItemTasks/" + backlogitemUId));            
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<ICollection<Task>>();
        }

        public ICollection<Task> GetUserTasks(string memberUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("UserTasks/" + SafeMemberUId(memberUId)));
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<ICollection<Task>>();
        }

        public ICollection<Task> GetUserUnassignedTasks(string memberUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("UnassignedTasks/?memberUId=" + SafeMemberUId(memberUId)));
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<ICollection<Task>>();
        }

        public ICollection<Task> GetUserOwnedTasks(string memberUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("UserOwnedTasks/" + SafeMemberUId(memberUId)));
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<ICollection<Task>>();
        }

        public Task GetTask(string taskUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("Tasks/" + taskUId));
            ClientHelper.HandleHTTPErrorCode(response);            
            return response.Content.ReadAs<Task>();
        }

        public TaskDetail GetTaskDetail(string taskUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("Tasks/" + taskUId + "/TaskDetail"));
            ClientHelper.HandleHTTPErrorCode(response);
            if (response.Content.ContentReadStream.Length == 0)
                return null;
            return response.Content.ReadAs<TaskDetail>();
        }

        public ICollection<BacklogItemEffectiveHours> GetItemTasksEffectiveHoursByProject(string projectUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("TaskEffectiveHours/?projectUId=" + projectUId));
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<ICollection<BacklogItemEffectiveHours>>();
        }


        public ICollection<TodayMemberPlannedHours> GetTodayMemberPlannedHours(string memberFromProjectUId, string membersUIds) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("TaskTodayPlanneHours/?memberFromProjectUId=" + memberFromProjectUId + "&membersUIds=" + membersUIds));
            return response.Content.ReadAs<ICollection<TodayMemberPlannedHours>>();
        }

        public int CreateTask(Task task) {
            var client = ClientHelper.GetClient(authorizator);            
            HttpResponseMessage response = client.Post(Url("Tasks/"), new ObjectContent<Task>(task, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);
            task.TaskNumber = response.Content.ReadAs<int>();
            return task.TaskNumber;
        }

        public void SaveTask(Task task, bool replanItem) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Put(Url("Tasks/?replanItem=" + replanItem), new ObjectContent<Task>(task, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);            
        }

        public System.DateTime ChangeTaskStatus(string taskUId, decimal addingHours, short status) {
            var client = ClientHelper.GetClient(authorizator);            
            string decimaStr = addingHours.ToString(System.Globalization.CultureInfo.InvariantCulture);
            HttpResponseMessage response = client.Put(Url("Tasks/" + taskUId + "/Status/?addingHours=" + decimaStr), new ObjectContent<short>(status, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<System.DateTime>();
        }

        public void ChangeTaskAssigneeUId(string taskUId, string taskAssigneeUId, bool replanItem) {
            var client = ClientHelper.GetClient(authorizator);                        
            HttpResponseMessage response = client.Put(Url("Tasks/" + taskUId + "/TaskAssigneeUId/?replanItem=" + replanItem), new ObjectContent<string>(taskAssigneeUId, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);            
        }

        public void ChangeTaskName(string taskUId, string taskName) {
            var client = ClientHelper.GetClient(authorizator);                                    
            HttpResponseMessage response = client.Put(Url("Tasks/" + taskUId + "/TaskName"), new ObjectContent<string>(taskName, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);
        }

        public void ChangeTaskItem(string taskUId, string backlogItemUId) {
            var client = ClientHelper.GetClient(authorizator);                                    
            HttpResponseMessage response = client.Put(Url("Tasks/" + taskUId + "/BacklogItemUId"), new ObjectContent<string>(backlogItemUId, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);
        }

        public void ChangeTaskPlannedHours(string taskUId, decimal plannedHours, bool replanItem) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Put(Url("Tasks/" + taskUId + "/PlannedHours/?replanItem=" + replanItem), new ObjectContent<decimal>(plannedHours, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);
        }

        public void ChangeTaskEffectiveHours(string taskUId, decimal effectiveHours, bool append) {
            var client = ClientHelper.GetClient(authorizator);                                                
            HttpResponseMessage response = client.Put(Url("Tasks/" + taskUId + "/EffectiveHours/?append=" + append), new ObjectContent<decimal>(effectiveHours, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);
        }

        public void ChangeTaskTrackStatus(string taskUId, bool finishAlso, bool isTracking) {            
            var client = ClientHelper.GetClient(authorizator);                                                
            string finishAlsoStr = finishAlso.ToString(System.Globalization.CultureInfo.InvariantCulture);
            HttpResponseMessage response = client.Post(Url("Tasks/" + taskUId + "/IsTracking/?finishAlso="+ finishAlsoStr), new ObjectContent<bool>(isTracking, JsonValueMediaTypeFormatter.DefaultMediaType));
            ClientHelper.HandleHTTPErrorCode(response);
        }

        public decimal GetReworkIndicator(string projectUId) {
            var client = ClientHelper.GetClient(authorizator);
            HttpResponseMessage response = client.Get(Url("ReworkIndicator/" + projectUId));
            ClientHelper.HandleHTTPErrorCode(response);
            return response.Content.ReadAs<decimal>();
        }

        public decimal GetProjectTotalEffectiveHours(string projectUId) {
            throw new NotImplementedException();
        }

        public decimal GetProjectTasksPrice(RoleHourCost[] costs) {
            throw new NotImplementedException();
        }

        public decimal GetTotalEffectiveHoursByItem(string backlogitemUId) {
            throw new NotImplementedException();
        }

        public bool DoesBacklogItemHasTasks(string backlogItemUId) {
            throw new NotImplementedException();
        }

        public bool DoesMemberHasAnyTaskAtProject(string projectUId, string memberUId) {
            throw new NotImplementedException();
        }

    }
}
